import { defineConfig } from "vite";
import path from "path";

export default defineConfig({
  /**
   * root - 项目根目录
   * 默认: process.cwd()
   */
  root: process.cwd(),

  /**
   * base - 开发或生产环境服务的公共基础路径
   * 默认: '/'
   * 有效值:
   * - '/': 部署在域名的根路径
   * - '/my-project/': 部署在域名下的子路径
   * - './': 相对路径（用于嵌入式部署）
   * - '': 空字符串或 './'（用于相对路径）
   * - 'http://cdn.example.com/assets/': 完整 URL（用于 CDN）
   */
  base: "/",

  /**
   * mode - 模式
   * 默认: 'development' 用于开发，'production' 用于构建
   */
  mode: "development",

  /**
   * define - 定义全局常量替换方式
   * 注意: 每个属性值都会在开发时被解析，构建时被静态替换
   */
  define: {
    // 字符串值需要显式引用
    __APP_VERSION__: JSON.stringify("1.0.0"),
    // 或者使用嵌套引号
    __API_URL__: '"https://api.example.com"',
    // 布尔值和数字可以直接写
    __DEV__: true,
    __BUILD_DATE__: Date.now(),
    // 对象需要序列化
    __FEATURE_FLAGS__: JSON.stringify({
      enableNewFeature: true,
      experimentalMode: false,
    }),
  },

  // ========== 插件配置 ==========

  /**
   * plugins - 要使用的插件数组
   */
  plugins: [
    // 插件按顺序调用
    // vue(), react(), 等
  ],

  // ========== 目录和缓存配置 ==========

  /**
   * publicDir - 静态资源服务的目录
   * 默认: 'public'
   * 该目录中的文件在开发期间在 / 处提供，并在构建时复制到 outDir 的根目录
   * 设置为 false 可以禁用此功能
   */
  publicDir: "public",

  /**
   * cacheDir - 存储缓存文件的目录
   * 默认: 'node_modules/.vite'
   * 此目录下会存储预打包的依赖项、esbuild 缓存等
   */
  cacheDir: "node_modules/.vite",

  // ========== 模块解析配置 ==========

  /**
   * resolve - 解析选项
   */
  resolve: {
    /**
     * alias - 路径别名
     * 条目可以是精确匹配，也可以是模糊匹配（以 /、./ 或 ../ 开头）
     */
    alias: {
      // 精确匹配
      "@": path.resolve(__dirname, "src"),
      components: path.resolve(__dirname, "src/components"),
      // 模糊匹配
      "/images/": path.resolve(__dirname, "src/assets/images"),
      // 对象形式提供更多选项
      "@/": {
        target: path.resolve(__dirname, "src"),
        // 是否匹配尾随 /
        trailingSlash: true,
      },
    },

    /**
     * dedupe - 强制 Vite 始终将列出的依赖项解析为同一副本
     * 如果遇到依赖项有多个版本时使用
     */
    dedupe: ["vue", "react", "react-dom"],

    /**
     * conditions - 包导出条件
     * 在解析包的导出字段时的附加条件
     */
    conditions: ["import", "module", "browser", "default"],

    /**
     * mainFields - 入口字段
     * 在解析包的入口点时尝试的字段列表
     */
    mainFields: ["module", "jsnext:main", "jsnext", "browser", "main"],

    /**
     * extensions - 导入时想要省略的扩展名列表
     */
    extensions: [".mjs", ".js", ".mts", ".ts", ".jsx", ".tsx", ".json", ".vue"],

    /**
     * preserveSymlinks - 是否保留符号链接
     * 设置为 true 时不会跟随符号链接到实际路径
     */
    preserveSymlinks: false,
  },

  // ========== HTML 配置 ==========

  /**
   * html - HTML 特定选项
   */
  html: {
    /**
     * cspNonce - 添加 nonce 到 script 标签
     * 用于内容安全策略 (CSP)
     */
    cspNonce: "random-nonce-string",
  },

  // ========== CSS 配置 ==========

  /**
   * css - CSS 配置选项
   */
  css: {
    /**
     * modules - CSS Modules 配置
     */
    modules: {
      /**
       * scopeBehaviour - 样式作用域行为
       * 'local' | 'global'
       */
      scopeBehaviour: "local",

      /**
       * generateScopedName - 生成局部类名
       * 字符串或函数
       */
      generateScopedName: "[name]__[local]___[hash:base64:5]",
      // 或者使用函数
      // generateScopedName: (name, filename, css) => {
      //   const file = path.basename(filename, '.css')
      //   return `_${file}_${name}_${hash(css)}`
      // },

      /**
       * hashPrefix - 生成 hash 时的前缀
       */
      hashPrefix: "prefix",

      /**
       * globalModulePaths - 全局模块路径
       * 匹配的 CSS 文件不会被模块化
       */
      globalModulePaths: [/\.global\.css$/, /node_modules/],

      /**
       * localsConvention - 类名转换规则
       * 'camelCase' | 'camelCaseOnly' | 'dashes' | 'dashesOnly'
       */
      localsConvention: "camelCase",
    },

    /**
     * postcss - PostCSS 配置
     * 可以是字符串（配置文件路径）、对象或函数
     */
    postcss: "./postcss.config.js",
    // 或者对象形式
    // postcss: {
    //   plugins: [
    //     require('autoprefixer'),
    //     require('postcss-preset-env')
    //   ]
    // },

    /**
     * preprocessorOptions - 预处理器选项
     */
    preprocessorOptions: {
      scss: {
        /**
         * additionalData - 在所有 SCSS 文件开头注入的代码
         */
        additionalData: `
          @import "@/styles/variables.scss";
          @import "@/styles/mixins.scss";
        `,
        // 其他 SCSS 选项
        charset: false,
      },
      less: {
        additionalData: `@import "@/styles/less-variables.less";`,
        modifyVars: {
          "primary-color": "#1890ff",
          "link-color": "#1890ff",
        },
        javascriptEnabled: true,
      },
      stylus: {
        additionalData: `@import "@/styles/stylus-variables.styl"`,
        define: {
          $primary: "#1890ff",
        },
      },
    },

    /**
     * preprocessorMaxWorkers - 预处理器最大工作线程数
     * 默认: 当前 CPU 核心数的一半
     * 设置为 0 禁用工作线程
     */
    preprocessorMaxWorkers: 4,

    /**
     * devSourcemap - 开发环境是否生成 sourcemap
     * 默认: true
     */
    devSourcemap: true,

    /**
     * transformer - CSS 转换器
     * 'postcss' | 'lightningcss'
     * 实验性功能
     */
    transformer: "postcss",

    /**
     * lightningcss - Lightning CSS 配置
     * 实验性功能，使用 Rust 编写的快速 CSS 转换器
     */
    lightningcss: {
      // Lightning CSS 特定选项
      targets: {
        chrome: 80,
        firefox: 70,
        safari: 13,
      },
      include: Features.Nesting,
      exclude: Features.LogicalProperties,
    },
  },

  // ========== JSON 配置 ==========

  /**
   * json - JSON 处理配置
   */
  json: {
    /**
     * namedExports - 是否支持命名导出
     * 默认: true
     */
    namedExports: true,

    /**
     * stringify - 是否将 JSON 转换为被解析的 JSON 字符串
     * 设置为 true 时，JSON 文件会被转换为 export default JSON.parse("...")
     * 这样在打包时更快，但会失去命名导出
     */
    stringify: false,
  },

  // ========== ESBuild 配置 ==========

  /**
   * esbuild - ESBuild 转换配置
   * 设置为 false 可禁用 ESBuild 转换
   */
  esbuild: {
    /**
     * 目标环境
     */
    target: "es2015",

    /**
     * 包含的文件
     */
    include: /\.(tsx?|jsx?|vue)$/,

    /**
     * 排除的文件
     */
    exclude: /node_modules/,

    /**
     * JSX 配置
     */
    jsx: "preserve", // 'transform' | 'preserve' | 'automatic'
    jsxFactory: "h",
    jsxFragment: "Fragment",
    jsxInject: `import React from 'react'`, // 自动注入

    /**
     * 压缩选项
     */
    minify: false,
    minifyIdentifiers: true,
    minifySyntax: true,
    minifyWhitespace: true,

    /**
     * Tree shaking
     */
    treeShaking: true,

    /**
     * 其他 ESBuild 选项
     */
    legalComments: "none",
    sourcemap: true,
    charset: "utf8",
  },

  // ========== 资源处理 ==========

  /**
   * assetsInclude - 指定其他文件类型作为静态资源处理
   * 可以是字符串、正则表达式或数组
   */
  assetsInclude: ["**/*.gltf", "**/*.glb", "**/*.wasm", /\.(csv|xml)$/],

  // ========== 日志和输出配置 ==========

  /**
   * logLevel - 控制台输出的日志级别
   * 'info' | 'warn' | 'error' | 'silent'
   */
  logLevel: "info",

  /**
   * customLogger - 自定义日志记录器
   */
  customLogger: {
    info(msg) {
      console.log(`[INFO] ${msg}`);
    },
    warn(msg) {
      console.warn(`[WARN] ${msg}`);
    },
    error(msg) {
      console.error(`[ERROR] ${msg}`);
    },
    clearScreen() {
      // 清屏逻辑
    },
  },

  /**
   * clearScreen - 是否清屏
   * 设置为 false 时，Vite 不会在控制台输出时清屏
   */
  clearScreen: true,

  // ========== 环境变量配置 ==========

  /**
   * envDir - 用于加载 .env 文件的目录
   * 可以是绝对路径，也可以是相对于项目根的路径
   */
  envDir: "./",

  /**
   * envPrefix - 以 envPrefix 开头的环境变量会通过 import.meta.env 暴露给客户端源码
   * 默认: 'VITE_'
   */
  envPrefix: "VITE_",

  // ========== 应用类型配置 ==========

  /**
   * appType - 应用类型
   * 'spa' - 单页应用（默认）
   * 'mpa' - 多页应用
   * 'custom' - 自定义框架
   */
  appType: "spa",

  // ========== 实验性功能 ==========

  /**
   * future - 实验性功能配置
   * 这些功能可能会在未来的版本中发生变化
   */
  future: {
    /**
     * 实验性功能标志
     */
    // 启用新的解析器
    // newResolver: true,
    // 启用新的优化器
    // newOptimizer: true,
    // 其他实验性功能...
  },
});
